import styles from './RoughMachining.module.scss'
import { FC, useState } from 'react'
import { useColorVar, useStyles } from '@/hooks/styles'
import { ViewTitle } from '@/components/universal/ViewTitle/ViewTitle'
import { Input, InputNumber, Slider, message } from 'antd'
import { observer } from 'mobx-react'
import { useGraphStore, useRoughStore } from '@/hooks'
import { UploadOutlined } from '@ant-design/icons'
import { Button, Upload } from 'antd'
import { ImageList } from '@/components/1RoughMachining/ImageList'
import { WeightSlider } from '@/components/1RoughMachining/WeightSlider'
import { BlockTitle } from '@/components/universal/BlockTitle/BlockTitle'
import { SvgIcon } from '@/components/icons'
import {
  IconText,
  IconImage,
  IconControl,
} from '@/components/icons/IconStyleFactory'
import axios from 'axios'
import { baseUrl, token, uploadUrl } from '@/config'
import { mobxProxyTrans } from '@/utils/basic'
import {
  addImageNodeInCanvas,
  clearImageInCanvas,
} from '@/components/3FineMachining/utils'
import { ImageNode } from '@/components/3FineMachining/ImageNode'

const { TextArea } = Input

export const RoughMachining: FC = observer(() => {
  const c = useColorVar()
  const styleClass = useStyles(styles)
  const [messageApi, contextHolder] = message.useMessage()
  const rough = useRoughStore()
  const graphStore = useGraphStore()

  const [batchValue, setBatchValue] = useState(40)
  const [genLoading, setGenLoading] = useState<boolean>(false)

  const onReset = () => {
    // reset
    rough.setDescription('')
    rough.resetReference()
    setBatchValue(40)
  }

  const handleGen = async () => {
    clearImageInCanvas(graphStore)
    const num_each_bath = 4
    const seed = -1
    const guidanceScale = 7.5
    setGenLoading(true)
    messageApi.loading({
      key: '1',
      content: `Generating (about ${Math.floor(batchValue * 0.72)}s)...`,
      duration: 60,
    })
    type postInput = {
      description: string
      references: string[]
      weight: number
      batchSize: number
      seed: number
      guidanceScale: number
      num_each_bath: number
    }
    console.log({
      description: rough.description,
      references: mobxProxyTrans(calcReferenceList(rough.reference)),
      weight: Number(rough.weight[1].toFixed(2)),
      batchSize: batchValue,
      num_each_bath: num_each_bath,
      seed: seed,
      guidanceScale: guidanceScale,
    })
    await axios
      .post(`${baseUrl}/rough/generate`, {
        description: rough.description,
        references: calcReferenceList(rough.reference),
        weight: Number(rough.weight[1].toFixed(2)),
        batchSize: batchValue,
        num_each_bath: num_each_bath,
        seed: seed,
      } as postInput)
      .then((res) => {
        // console.log(res.data.data)
        setGenLoading(false)
        messageApi.success({
          key: '1',
          content: `Successfully generated ${batchValue} images`,
        })
        rough.setCurrentStyleID(null) // 点击Generate之后，默认创建一个新的风格
        // 清空画布
        clearImageInCanvas(graphStore)
        const temp = res.data.data as Array<{ id: string; url: string }>
        for (let i = 0; i < temp.length; i++) {
          addImageNodeInCanvas({
            graph: graphStore.graph,
            imageID: temp[i]['id'],
            component: ({ node, graph }) => (
              <ImageNode
                node={node}
                graph={graph}
                imageID={temp[i]['id']}
                url={temp[i]['url']}
              />
            ),
            position: [72 + (i % 10) * 104, 278 + Math.trunc(i / 10) * 86],
          })
        }
        /* graphStore.setImageData(
          res.data.data as Array<{ id: string; url: string }>
        ) */
        return
      })
      .catch((error) => {
        setGenLoading(false)
        messageApi.error({ key: '1', content: 'Generation failed' })
        console.log('error', error)
        return
      })
  }

  const calcReferenceList = (references: string[]) => {
    const result = []
    for (let i = 0; i < 4; i++) {
      if (references[i] !== '') {
        result.push(references[i])
      }
    }
    return result
  }

  return (
    <div {...styleClass(['layout'])}>
      {contextHolder}
      <ViewTitle text={'Coarse Machining'} />
      <div {...styleClass(['content'])}>
        {/* Description */}
        <div {...styleClass(['block1'])}>
          <BlockTitle
            title={'Description'}
            description={'Style description'}
            icon={<SvgIcon icon={IconText} />}
          />
          <TextArea
            {...styleClass(['block1-textarea'])}
            placeholder={'Enter your style description'}
            // autoSize={{ minRows: 3, maxRows: 3 }}
            value={rough.description}
            onChange={(e) => rough.setDescription(e.target.value)}
          />
        </div>

        {/* Reference */}
        <div {...styleClass(['block2'])}>
          <BlockTitle
            title={'Reference'}
            description={'Style references'}
            icon={<SvgIcon icon={IconImage} />}
          />
          <Upload
            accept="image/*"
            headers={{ Authorization: token }}
            action={uploadUrl}
            onChange={(file) => {
              if ('response' in file.file) {
                const url = file.file.response.data as string
                rough.addReference(url)
              }
            }}
          >
            <Button
              // icon={<UploadOutlined rev={null} />}
              {...styleClass(['block2-button'])}
            >
              <div {...styleClass(['block2-button-text'])}>
                <UploadOutlined rev={null} style={{ marginRight: 8 }} />
                Upload
              </div>
            </Button>
          </Upload>
          <ImageList />
        </div>

        {/* Gen Controls */}
        <div {...styleClass(['block3'])}>
          <BlockTitle
            title={'Gen Controls'}
            icon={<SvgIcon icon={IconControl} />}
          />

          <div {...styleClass(['block3-weight-layout'])}>
            <div {...styleClass(['block3-weight-text'])}>
              Mixture Ratio (desc. - ref.)
            </div>
            <WeightSlider />
          </div>

          <div {...styleClass(['block3-batch-layout'])}>
            <div {...styleClass(['block3-batch-text'])}>Total Generation</div>
            <div {...styleClass(['block3-batch-slider-layout'])}>
              <Slider
                min={10}
                max={50}
                onChange={(newV) => setBatchValue(newV)}
                value={typeof batchValue === 'number' ? batchValue : 40}
                {...styleClass(['block3-batch-slider-slider'])}
              />
              <InputNumber
                size={'small'}
                min={20}
                max={60}
                value={batchValue}
                onChange={(newV) => setBatchValue(newV)}
                {...styleClass(['block3-batch-slider-input'])}
              />
            </div>
          </div>
        </div>

        <div {...styleClass(['button-group'])}>
          <Button
            type={'primary'}
            {...styleClass(['button-group-button1'])}
            loading={genLoading}
            onClick={() => handleGen()}
          >
            Generate
          </Button>
          <Button
            {...styleClass(['button-group-button2'])}
            onClick={() => onReset()}
          >
            <div {...styleClass(['button-group-text'], { color: '#AD9F67' })}>
              Reset
            </div>
          </Button>
        </div>
      </div>
    </div>
  )
})
